
#ifndef _OSAPI_SOCKET_H
#define _OSAPI_SOCKET_H

/* ��api����define��ʹ��linux/win32�������һ�µ� */
#ifdef WIN32
// windows �µ�socket����
#include <winsock2.h>
#include <ws2tcpip.h>

typedef SOCKET socket_t;

#if defined _MSC_VER &&_MSC_VER <= 1400
	#define OS_INVALID_SOCKET (unsigned int)(~0)
#else
	#define OS_INVALID_SOCKET INVALID_SOCKET
#endif


#define socket_open socket
#define socket_close closesocket
#define socket_ioctl  ioctlsocket
#else
// linux�µ�socket����
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <sys/time.h>
#include <fcntl.h>

typedef int socket_t;
#define OS_INVALID_SOCKET -1

#define socket_open socket
#define socket_close close
#define socket_ioctl  ioctl
#endif

#define socket_accept  accept
#define socket_bind      bind
#define socket_connect connect
#define socket_listen    listen
#define socket_send     send
#define socket_recv      recv
#define socket_sendto   sendto
#define socket_recvfrom recvfrom
#define socket_select    select
#define socket_setsockopt setsockopt
#define socket_getsockopt getsockopt

/////////////////////////////////////////////////////////////
/* socket��ַ */
typedef struct  
{
	struct sockaddr_in iAddr;
}os_sockaddr_t;

#define OS_SOCKET_ERROR -1

int os_init_sock_envir();

void os_sockaddr_set(os_sockaddr_t* sa, const char* ip, unsigned short port);
void os_sockaddr_setip(os_sockaddr_t* sa, const char* ip);
void os_sockaddr_setip_n(os_sockaddr_t* sa, unsigned int ip);
void os_sockaddr_setport(os_sockaddr_t* sa, unsigned short port);

void os_sockaddr_get(os_sockaddr_t* sa,  char* ip, unsigned short* port);
void os_sockaddr_getip(os_sockaddr_t* sa, char* ip);
unsigned int os_sockaddr_getip_n(os_sockaddr_t* sa);
unsigned short os_sockaddr_getport(os_sockaddr_t* sa);

/////////////////////////////////////////////////////////////
/* socket */
typedef socket_t os_socket_t;
int os_sock_setopt_recvtimeout(os_socket_t s, int ms); 
int os_sock_setopt_sendtimeout(os_socket_t s, int ms);
int os_sock_getopt_recvtimeout(os_socket_t s); 
int os_sock_getopt_sendtimeout(os_socket_t s);

int os_sock_ioctl_setnoblockio(os_socket_t s);
int os_sock_setopt_reuseaddr(os_socket_t s, int reuse);
int os_sock_setopt_keeplive(os_socket_t s, int keeplive);

int os_sock_getpeeraddr(os_socket_t s, os_sockaddr_t* addr) ;
int os_sock_getlocaladdr(os_socket_t s, os_sockaddr_t* addr) ;

/////////////////////////////////////////////////////////////
/* tcp socket */
int os_tcpsock_open(os_socket_t* s, int reuse );
int os_tcpsock_openat(os_socket_t* s, const os_sockaddr_t* sa, int reuse);
void os_tcpsock_close(os_socket_t* s);

// set backlog default to 16
int os_tcpsock_listen(os_socket_t s, int backlog);
int os_tcpsock_accept(os_socket_t s, os_socket_t * peer);

// �ͻ���
int os_tcpsock_connect(os_socket_t s, const os_sockaddr_t * sa);

// ���ͽ���
int os_tcpsock_send(os_socket_t s, const void* buf, int len, int nFlags);
int os_tcpsock_recv(os_socket_t s, void* buf, int len, int nFlags);

/////////////////////////////////////////////////////////////
/* udp socket */
int os_udpsock_open(os_socket_t* s, int reuse );
int os_udpsock_openat(os_socket_t* s, const os_sockaddr_t* sa, int reuse);
void os_udpsock_close(os_socket_t* s);

int os_udpsock_sendto(os_socket_t s, const void* buf, int len, const os_sockaddr_t*  peer);
int os_udpsock_recvfrom(os_socket_t s, void* buf, int max_len, os_sockaddr_t* peer);

/////////////////////////////////////////////////////////////
/* multicast socket */
int os_mcast_open(os_socket_t* s, const char* mcast_ip, int port, const char* local_ip);
void os_mcast_close(os_socket_t* s);

/* ���Ͷಥʱ��ʹ����ͨUdpSock + �ಥ·�ɼ��� */
//int SendTo(const void* buf, int len, const OS_SockAddr& peer);
int os_mcast_recvfrom(os_socket_t s, void* buf, int max_len, const os_sockaddr_t* peer);

#endif

